import sys
import yaml
from PyQt6.QtWidgets import (QApplication, QMainWindow, QTableWidget, 
                           QTableWidgetItem, QVBoxLayout, QWidget, QInputDialog, QMessageBox, QPushButton, QHBoxLayout, QFileDialog, QComboBox,
                           QMenuBar, QMenu, QDialog, QLabel, QLineEdit, QFormLayout, QHeaderView, QGridLayout, QSizePolicy, QScrollArea)
from PyQt6.QtCore import Qt, QRect
import openpyxl
import re
import os

USER_HEADER = ["金额", "单双", "盈亏"]
USER_TYPE = "user"
NORMAL_TYPE = "normal"

class ConfigurableTable(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Configurable Table - 多级表头")
        
        # 加载配置
        self.load_config()
        
        # 统计用户列和普通列
        self.user_col_indices = [idx for idx, col in enumerate(self.config['columns']) if col.get('type') == USER_TYPE]
        self.normal_col_indices = [idx for idx, col in enumerate(self.config['columns']) if col.get('type') != USER_TYPE]
        self.user_count = len(self.user_col_indices) // 3
        self.total_columns = len(self.config['columns'])
        self.data = self.config.get('data', [])
        self.data_rows = max(len(self.data), 100)
        
        # 创建菜单栏
        menubar = self.menuBar()
        
        # 创建设置菜单
        settings_menu = menubar.addMenu("设置")
        
        # 创建用户管理子菜单
        user_menu = QMenu("用户管理", self)
        settings_menu.addMenu(user_menu)
        
        # 添加用户动作
        add_user_action = user_menu.addAction("添加用户")
        add_user_action.triggered.connect(self.add_user)
        
        # 删除用户动作
        remove_user_action = user_menu.addAction("删除用户")
        remove_user_action.triggered.connect(self.remove_user)
        # 如果只有一个用户，禁用删除操作
        if self.user_count <= 1:
            remove_user_action.setEnabled(False)
        
        # 创建中心部件和布局
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        main_layout = QVBoxLayout(central_widget)
        main_layout.setSpacing(0)
        main_layout.setContentsMargins(0, 0, 0, 0)
        
        # 按钮布局
        btn_layout = QHBoxLayout()
        self.clear_btn = QPushButton("清空")
        self.clear_btn.clicked.connect(self.clear_and_reset_users)
        btn_layout.addWidget(self.clear_btn)
        # 导出按钮
        self.export_btn = QPushButton("导出")
        self.export_btn.clicked.connect(self.export_to_excel)
        btn_layout.addWidget(self.export_btn)
        # 导入按钮
        self.import_btn = QPushButton("导入")
        self.import_btn.clicked.connect(self.import_from_excel)
        btn_layout.addWidget(self.import_btn)
        btn_layout.addStretch()
        main_layout.addLayout(btn_layout)
        
        # 创建滚动区域
        scroll_area = QScrollArea()
        scroll_area.setWidgetResizable(True)
        scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)
        scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)
        
        # 创建表头widget（放在滚动区域外部）
        self.header_widget = QWidget()
        self.header_layout = QHBoxLayout(self.header_widget)
        self.header_layout.setSpacing(0)
        self.header_layout.setContentsMargins(0, 0, 0, 0)
        main_layout.addWidget(self.header_widget)
        
        # 添加滚动区域到主布局
        main_layout.addWidget(scroll_area)
        
        # 创建滚动区域的内容widget
        scroll_content = QWidget()
        scroll_layout = QVBoxLayout(scroll_content)
        scroll_layout.setSpacing(0)
        scroll_layout.setContentsMargins(0, 0, 0, 0)
        
        # 创建水平布局来容纳垂直表头和表格区域
        table_layout = QHBoxLayout()
        table_layout.setSpacing(0)
        table_layout.setContentsMargins(0, 0, 0, 0)
        
        # 创建垂直表头widget
        self.row_header_widget = QWidget()
        self.row_header_layout = QVBoxLayout(self.row_header_widget)
        self.row_header_layout.setSpacing(0)
        self.row_header_layout.setContentsMargins(0, 0, 0, 0)
        table_layout.addWidget(self.row_header_widget)
        
        # 创建表格区域容器
        table_container = QWidget()
        table_container_layout = QVBoxLayout(table_container)
        table_container_layout.setSpacing(0)
        table_container_layout.setContentsMargins(0, 0, 0, 0)
        
        # 创建表格
        self.table = QTableWidget()
        self.table.verticalHeader().setVisible(False)  # 隐藏原有的垂直表头
        self.table.horizontalHeader().setVisible(False)
        self.table.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)  # 禁用水平滚动条
        self.table.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)    # 禁用垂直滚动条
        
        self.table.setColumnCount(self.total_columns)
        self.table.setRowCount(self.data_rows + 1)  # 第一行为表头
        
        table_container_layout.addWidget(self.table)
        table_layout.addWidget(table_container)
        
        scroll_layout.addLayout(table_layout)
        
        # 设置滚动区域的widget
        scroll_area.setWidget(scroll_content)
        
        # 连接滚动区域的水平滚动信号
        scroll_area.horizontalScrollBar().valueChanged.connect(self.sync_header_position)
        
        # 设置多级表头
        self.init_multilevel_header()
        # 填充数据
        self.fill_table_data()
        # 设置可编辑性
        self.set_editable()
        # 其它表格属性
        self.table.setAlternatingRowColors(True)
        self.table.setSelectionBehavior(QTableWidget.SelectionBehavior.SelectRows)
        # 连接cellChanged信号
        self.table.cellChanged.connect(self.handle_first_col_input)
        self.table.cellChanged.connect(self.handle_user_amount_input)
        self.table.cellChanged.connect(self.handle_header_changed)
        self.table.cellDoubleClicked.connect(self.handle_user_amount_edit_start)
        
        # 更新表头widget
        self.update_header_widget()
        # 更新行号widget
        self.update_row_header_widget()
        # 防止刷新后窗口黑屏
        self.show()

    def update_row_header_widget(self):
        # 清除旧的行号内容
        for i in reversed(range(self.row_header_layout.count())):
            item = self.row_header_layout.itemAt(i)
            widget = item.widget()
            if widget is not None:
                widget.setParent(None)
            else:
                self.row_header_layout.removeItem(item)
        
        # 为每一行添加行号label
        for row in range(1, self.table.rowCount()):
            label = QLabel(str(row))
            label.setFixedHeight(self.table.rowHeight(row))
            label.setAlignment(Qt.AlignmentFlag.AlignCenter)
            label.setStyleSheet("""
                QLabel {
                    background-color: #f0f0f0;
                    border: 1px solid #d0d0d0;
                    border-right: none;
                    border-top: none;
                }
            """)
            self.row_header_layout.addWidget(label)
        
        # 设置行号widget的固定宽度
        self.row_header_widget.setFixedWidth(40)  # 可以根据需要调整宽度
        
        # 添加弹性空间
        self.row_header_layout.addStretch()

    def sync_header_position(self, value):
        # 只移动header_container，不移动header_widget本身
        if hasattr(self, 'header_container'):
            self.header_container.move(-value, 0)

    def update_header_widget(self):
        # 清除旧的表头内容
        for i in reversed(range(self.header_layout.count())): 
            self.header_layout.itemAt(i).widget().setParent(None)
        
        # 只用一行表头
        self.header_container = QWidget()
        h_layout = QHBoxLayout(self.header_container)
        h_layout.setSpacing(0)
        h_layout.setContentsMargins(0, 0, 0, 0)
        # 空白label对齐垂直表头
        empty_label = QLabel()
        empty_label.setFixedWidth(40)
        empty_label.setFixedHeight(40)
        empty_label.setStyleSheet("""
            QLabel {
                background-color: #f0f0f0;
                border: 1px solid #d0d0d0;
                border-right: none;
                border-bottom: none;
            }
        """)
        h_layout.addWidget(empty_label)
        col = 0
        while col < self.table.columnCount():
            col_type = self.config['columns'][col].get('type')
            if col_type == USER_TYPE:
                header_text = self.table.item(0, col).text() if self.table.item(0, col) else ""
                label = QLabel(header_text)
                total_width = sum(self.table.columnWidth(i) for i in range(col, col + 3))
                label.setFixedWidth(total_width)
                label.setFixedHeight(40)
                label.setAlignment(Qt.AlignmentFlag.AlignCenter)
                label.setStyleSheet("""
                    QLabel {
                        background-color: #f0f0f0;
                        border: 1px solid #d0d0d0;
                        border-bottom: none;
                    }
                """)
                # 绑定双击事件
                label.mouseDoubleClickEvent = self.make_user_header_editable(label, col)
                h_layout.addWidget(label)
                col += 3
            else:
                header_text = self.table.item(0, col).text() if self.table.item(0, col) else ""
                label = QLabel(header_text)
                label.setFixedWidth(self.table.columnWidth(col))
                label.setFixedHeight(40)
                label.setAlignment(Qt.AlignmentFlag.AlignCenter)
                label.setStyleSheet("""
                    QLabel {
                        background-color: #f0f0f0;
                        border: 1px solid #d0d0d0;
                        border-bottom: none;
                    }
                """)
                h_layout.addWidget(label)
                col += 1
        self.header_layout.addWidget(self.header_container)
        # 设置高度
        self.header_widget.setFixedHeight(40)
        # header整体右移2px
        self.header_layout.setContentsMargins(2, 0, 0, 0)
        # 隐藏table的第0行
        self.table.setRowHidden(0, True)
        # 同步宽度
        def update_header_width():
            total_width = 40
            for col in range(self.table.columnCount()):
                total_width += self.table.columnWidth(col)
            self.header_widget.setFixedWidth(total_width)
            self.header_container.setFixedWidth(total_width)
        self.table.horizontalHeader().sectionResized.connect(update_header_width)
        update_header_width()

    def make_user_header_editable(self, label, col):
        def handler(event):
            # 只允许左键双击
            if event.button() != Qt.MouseButton.LeftButton:
                return
            parent = label.parentWidget()
            layout = parent.layout()
            idx = layout.indexOf(label)
            # 创建QLineEdit替换QLabel
            edit = QLineEdit(label.text())
            edit.setFixedWidth(label.width())
            edit.setFixedHeight(label.height())
            edit.setAlignment(Qt.AlignmentFlag.AlignCenter)
            edit.setStyleSheet(label.styleSheet())
            layout.removeWidget(label)
            label.deleteLater()
            layout.insertWidget(idx, edit)
            edit.setFocus()
            edit.selectAll()
            # 处理编辑完成
            def finish_edit():
                new_name = edit.text().strip()
                if not new_name:
                    new_name = label.text()
                # 更新所有相关用户列名
                user_indices = [i for i, c in enumerate(self.config['columns']) if c.get('type') == USER_TYPE]
                user_index = user_indices.index(col)
                user_group = user_index // 3
                for i in range(3):
                    idx = user_indices[user_group * 3 + i]
                    self.config['columns'][idx]['name'] = new_name
                    if i == 0:
                        self.table.item(0, idx).setText(new_name)
                # 刷新表头
                self.update_header_widget()
            edit.editingFinished.connect(finish_edit)
        return handler

    def load_config(self):
        try:
            if not os.path.exists('config.yaml'):
                # 弹出用户配置对话框
                user_count, ok = QInputDialog.getInt(self, "配置用户数量", "请输入用户数量：", 2, 1, 100)
                if ok:
                    # 创建默认配置
                    default_config = {
                        'columns': [
                            {
                                'name': '开奖号码',
                                'type': 'normal',
                                'width': 80,
                                'editable': True
                            },
                            {
                                'name': '单双',
                                'type': 'normal',
                                'width': 60,
                                'editable': False
                            },
                            {
                                'name': '差额',
                                'type': 'normal',
                                'width': 80,
                                'editable': False
                            }
                        ],
                        'data': []
                    }
                    
                    # 生成用户列
                    for i in range(user_count):
                        for j in range(3):
                            default_config['columns'].append({
                                'name': f'用户{i+1}',
                                'type': USER_TYPE,
                                'width': 60,
                                'editable': True
                            })
                    
                    # 添加其他列
                    default_config['columns'].extend([
                        {
                            'name': '利润',
                            'type': 'normal',
                            'width': 80,
                            'editable': False
                        },
                        {
                            'name': '系数',
                            'type': 'normal',
                            'width': 60,
                            'editable': True
                        },
                        {
                            'name': '备注1',
                            'type': 'normal',
                            'width': 100,
                            'editable': True
                        },
                        {
                            'name': '总输赢',
                            'type': 'normal',
                            'width': 80,
                            'editable': False
                        },
                        {
                            'name': '减半操作',
                            'type': 'button',
                            'width': 120,
                            'editable': False
                        }
                    ])
                    
                    # 写入默认配置文件
                    with open('config.yaml', 'w', encoding='utf-8') as file:
                        yaml.dump(default_config, file, allow_unicode=True)
                    self.config = default_config
                else:
                    # 用户取消，创建默认配置（一个用户）
                    default_config = {
                        'columns': [
                            {
                                'name': '开奖号码',
                                'type': 'normal',
                                'width': 80,
                                'editable': True
                            },
                            {
                                'name': '单双',
                                'type': 'normal',
                                'width': 60,
                                'editable': False
                            },
                            {
                                'name': '差额',
                                'type': 'normal',
                                'width': 80,
                                'editable': False
                            },
                            {
                                'name': '用户1',
                                'type': USER_TYPE,
                                'width': 60,
                                'editable': True
                            },
                            {
                                'name': '用户1',
                                'type': USER_TYPE,
                                'width': 60,
                                'editable': True
                            },
                            {
                                'name': '用户1',
                                'type': USER_TYPE,
                                'width': 60,
                                'editable': True
                            },
                            {
                                'name': '利润',
                                'type': 'normal',
                                'width': 80,
                                'editable': False
                            },
                            {
                                'name': '系数',
                                'type': 'normal',
                                'width': 60,
                                'editable': True
                            },
                            {
                                'name': '备注1',
                                'type': 'normal',
                                'width': 100,
                                'editable': True
                            },
                            {
                                'name': '总输赢',
                                'type': 'normal',
                                'width': 80,
                                'editable': False
                            },
                            {
                                'name': '减半操作',
                                'type': 'button',
                                'width': 120,
                                'editable': False
                            }
                        ],
                        'data': []
                    }
                    # 写入默认配置文件
                    with open('config.yaml', 'w', encoding='utf-8') as file:
                        yaml.dump(default_config, file, allow_unicode=True)
                    self.config = default_config
            else:
                with open('config.yaml', 'r', encoding='utf-8') as file:
                    self.config = yaml.safe_load(file)
        except Exception as e:
            print(f"Error loading config: {e}")
            sys.exit(1)

    def generate_user_columns(self, user_count):
        # 普通列（前3个）
        base_columns = [col for col in self.config.get('columns', []) if col.get('type') != USER_TYPE][:3]
        # 汇总类列（type=normal，且不是前3个）
        all_normals = [col for col in self.config.get('columns', []) if col.get('type') != USER_TYPE]
        summary_columns = [col for col in all_normals[3:] if col['name'] not in ['单双赢半', '总输赢利润']]
        # 用户列
        user_columns = []
        for i in range(1, user_count + 1):
            for _ in range(3):
                user_columns.append({
                    'name': f'用户{i}',
                    'type': USER_TYPE,
                    'width': 60,
                    'editable': True
                })
        # 添加减半按钮列（只添加一次）
        if not any(col.get('type') == 'button' for col in summary_columns):
            summary_columns.append({
                'name': '减半操作',
                'type': 'button',
                'width': 120,
                'editable': False
            })
        # 合并：普通列 + 用户列 + 汇总列
        self.config['columns'] = base_columns + user_columns + summary_columns

    def prompt_and_reset_users(self):
        user_count, ok = QInputDialog.getInt(self, "配置用户数量", "请输入用户数量：", 2, 1, 100)
        if ok:
            self.generate_user_columns(user_count)
            self.config['data'] = []
            with open('config.yaml', 'w', encoding='utf-8') as file:
                yaml.dump(self.config, file, allow_unicode=True)
        else:
            QMessageBox.warning(self, "未配置用户数量", "未配置用户数量，程序将退出。")
            sys.exit(0)
        # 重新加载配置并刷新表格
        self.load_config()
        self.user_col_indices = [idx for idx, col in enumerate(self.config['columns']) if col.get('type') == USER_TYPE]
        self.normal_col_indices = [idx for idx, col in enumerate(self.config['columns']) if col.get('type') != USER_TYPE]
        self.user_count = len(self.user_col_indices) // 3
        self.total_columns = len(self.config['columns'])
        self.data = self.config.get('data', [])
        self.data_rows = max(len(self.data), 100)
        self.table.clear()  # 清空所有内容，包括表头和数据
        self.table.setRowCount(0)
        self.table.setColumnCount(0)
        self.table.setColumnCount(self.total_columns)
        self.table.setRowCount(self.data_rows + 1)
        self.init_multilevel_header()
        self.fill_table_data()
        self.set_editable()

    def clear_and_reset_users(self):
        # 添加确认对话框
        reply = QMessageBox.question(self, '确认清空', 
                                   '确定要清空所有数据吗？此操作不可恢复。',
                                   QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
                                   QMessageBox.StandardButton.No)
        
        if reply != QMessageBox.StandardButton.Yes:
            return
            
        # 保存当前配置
        current_config = self.config.copy()
        
        # 清空数据
        current_config['data'] = []
        
        # 写入配置文件
        with open('config.yaml', 'w', encoding='utf-8') as file:
            yaml.dump(current_config, file, allow_unicode=True)
            
        # 重新加载配置并刷新表格
        self.load_config()
        self.user_col_indices = [idx for idx, col in enumerate(self.config['columns']) if col.get('type') == USER_TYPE]
        self.normal_col_indices = [idx for idx, col in enumerate(self.config['columns']) if col.get('type') != USER_TYPE]
        self.user_count = len(self.user_col_indices) // 3
        self.total_columns = len(self.config['columns'])
        self.data = self.config.get('data', [])
        self.data_rows = max(len(self.data), 100)
        
        # 设置表格大小
        self.table.setColumnCount(self.total_columns)
        self.table.setRowCount(self.data_rows + 1)
        
        # 初始化表头和数据
        self.init_multilevel_header()
        self.fill_table_data()
        self.set_editable()

    def init_multilevel_header(self):
        self.table.setRowCount(self.data_rows + 1)  # 第一行为表头
        col = 0
        while col < self.total_columns:
            col_type = self.config['columns'][col].get('type')
            col_name = self.config['columns'][col]['name']
            if col_type == USER_TYPE:
                # 合并3列
                self.table.setSpan(0, col, 1, 3)
                item = QTableWidgetItem(col_name)
                item.setFlags(Qt.ItemFlag.ItemIsEnabled | Qt.ItemFlag.ItemIsEditable)
                item.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
                self.table.setItem(0, col, item)
                col += 3
            elif col_type == 'button':
                # 按钮列
                item = QTableWidgetItem(col_name)
                item.setFlags(Qt.ItemFlag.ItemIsEnabled)
                item.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
                self.table.setItem(0, col, item)
                col += 1
            else:
                item = QTableWidgetItem(col_name)
                item.setFlags(Qt.ItemFlag.ItemIsEnabled)
                item.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
                self.table.setItem(0, col, item)
                col += 1
        self.table.setRowHeight(0, 30)
        
        # 设置列宽
        total_width = 2  # 边框宽度
        for idx, col in enumerate(self.config['columns']):
            width = col['width']
            self.table.setColumnWidth(idx, width)
            total_width += width
        
        # 设置表格的固定宽度，防止出现空白
        self.table.setFixedWidth(total_width)
        
        # 获取屏幕尺寸
        screen = QApplication.primaryScreen()
        screen_width = screen.geometry().width()
        screen_height = screen.geometry().height()
        
        # 调整窗口大小以适应表格
        self.adjustSize()
        
        # 设置窗口最小宽度，防止用户将窗口调整得太小
        min_width = min(total_width + 60, 1200)  # 默认最大1200px，加60是为了留一些边距和行号宽度
        self.setMinimumWidth(min_width)
        
        # 设置窗口最大宽度为屏幕宽度
        self.setMaximumWidth(screen_width)
        
        # 设置默认高度为800px，但不超过屏幕高度
        default_height = min(800, screen_height)
        self.resize(self.width(), default_height)

    def handle_header_changed(self, row, col):
        # 只处理表头行（第0行）的用户名称列
        if row != 0:
            return
            
        item = self.table.item(row, col)
        if not item:
            return
            
        col_type = self.config['columns'][col].get('type')
        if col_type != USER_TYPE:
            return
            
        # 获取新的用户名称
        new_name = item.text().strip()
        if not new_name:
            # 如果名称为空，恢复原来的名称
            item.setText(self.config['columns'][col]['name'])
            return
            
        # 更新所有相同用户的列名
        user_indices = [i for i, c in enumerate(self.config['columns']) if c.get('type') == USER_TYPE]
        user_index = user_indices.index(col)
        user_group = user_index // 3
        
        for i in range(3):
            idx = user_indices[user_group * 3 + i]
            self.config['columns'][idx]['name'] = new_name
            if i == 0:  # 只在第一列显示名称
                self.table.item(0, idx).setText(new_name)
        
        # 更新表头widget
        self.update_header_widget()

    def fill_table_data(self):
        for row_idx in range(self.data_rows):
            row_data = self.data[row_idx] if row_idx < len(self.data) else []
            for col_idx, col_config in enumerate(self.config['columns']):
                # 减半按钮列
                if col_config.get('type') == 'button':
                    # 创建按钮容器
                    button_widget = QWidget()
                    button_layout = QHBoxLayout(button_widget)
                    button_layout.setContentsMargins(2, 2, 2, 2)
                    button_layout.setSpacing(2)
                    
                    # 创建单减半按钮
                    single_btn = QPushButton("单减半")
                    single_btn.setFixedHeight(25)
                    single_btn.clicked.connect(lambda checked, r=row_idx + 1: self.handle_half_amount(r, '单'))
                    button_layout.addWidget(single_btn)
                    
                    # 创建双减半按钮
                    double_btn = QPushButton("双减半")
                    double_btn.setFixedHeight(25)
                    double_btn.clicked.connect(lambda checked, r=row_idx + 1: self.handle_half_amount(r, '双'))
                    button_layout.addWidget(double_btn)
                    
                    self.table.setCellWidget(row_idx + 1, col_idx, button_widget)
                    continue
                    
                # 利润列自动计算
                if col_config['name'] == '利润':
                    value = self.calculate_profit(row_idx + 1)
                    item = QTableWidgetItem(value)
                    item.setFlags(Qt.ItemFlag.ItemIsSelectable | Qt.ItemFlag.ItemIsEnabled)
                    # 如果是第一列且值为34或35，设置文本颜色为红色
                    if col_idx == 0 and item.text() in ['34', '35']:
                        item.setForeground(Qt.GlobalColor.red)
                    self.table.setItem(row_idx + 1, col_idx, item)
                    continue
                # 总输赢列自动计算
                if col_config['name'] == '总输赢':
                    value = self.calculate_total_win(row_idx + 1)
                    item = QTableWidgetItem(value)
                    item.setFlags(Qt.ItemFlag.ItemIsSelectable | Qt.ItemFlag.ItemIsEnabled)
                    # 如果是第一列且值为34或35，设置文本颜色为红色
                    if col_idx == 0 and item.text() in ['34', '35']:
                        item.setForeground(Qt.GlobalColor.red)
                    self.table.setItem(row_idx + 1, col_idx, item)
                    continue
                # 差额列自动计算
                if col_config['name'] == '差额':
                    value = self.calculate_diff(row_idx + 1)
                    item = QTableWidgetItem(value)
                    item.setFlags(Qt.ItemFlag.ItemIsSelectable | Qt.ItemFlag.ItemIsEnabled)
                    # 如果是第一列且值为34或35，设置文本颜色为红色
                    if col_idx == 0 and item.text() in ['34', '35']:
                        item.setForeground(Qt.GlobalColor.red)
                    self.table.setItem(row_idx + 1, col_idx, item)
                    continue
                # 第二列自动显示单双，不可编辑
                if col_idx == 1:
                    if row_idx < len(self.data):
                        first_col_val = str(row_data[0]) if len(row_data) > 0 else ''
                        if re.match(r'^[1-6]{2}$', first_col_val):
                            s = int(first_col_val[0]) + int(first_col_val[1])
                            value = '单' if s % 2 == 1 else '双'
                        else:
                            value = ''
                    else:
                        value = ''
                    item = QTableWidgetItem(value)
                    item.setFlags(Qt.ItemFlag.ItemIsSelectable | Qt.ItemFlag.ItemIsEnabled)
                    # 如果是第一列且值为34或35，设置文本颜色为红色
                    if col_idx == 0 and item.text() in ['34', '35']:
                        item.setForeground(Qt.GlobalColor.red)
                    self.table.setItem(row_idx + 1, col_idx, item)
                    continue
                # 用户第二列用下拉框（无论有无数据都要显示）
                if col_config.get('type') == 'user':
                    user_indices = [i for i, c in enumerate(self.config['columns']) if c.get('type') == 'user']
                    user_index = user_indices.index(col_idx)
                    # 用户第三列（盈亏）自动计算并累计
                    if user_index % 3 == 2:
                        value = self.calculate_user_profit_accum(row_idx + 1, col_idx)
                        item = QTableWidgetItem(value)
                        item.setFlags(Qt.ItemFlag.ItemIsSelectable | Qt.ItemFlag.ItemIsEnabled)
                        # 如果是第一列且值为34或35，设置文本颜色为红色
                        if col_idx == 0 and item.text() in ['34', '35']:
                            item.setForeground(Qt.GlobalColor.red)
                        self.table.setItem(row_idx + 1, col_idx, item)
                        continue
                    if user_index % 3 == 1:
                        combo = QComboBox()
                        combo.addItems(['', '单', '双'])
                        val = row_data[col_idx] if col_idx < len(row_data) else ''
                        combo.setCurrentText(str(val) if val in ['单', '双'] else '')
                        combo.currentTextChanged.connect(lambda _, r=row_idx + 1, c=col_idx: self.handle_user_ds_changed(r, c))
                        self.table.setCellWidget(row_idx + 1, col_idx, combo)
                        continue
                # 系数列默认为空
                if col_config['name'] == '系数':
                    value = str(row_data[col_idx]) if col_idx < len(row_data) and row_data[col_idx] != '' else ''
                else:
                    value = str(row_data[col_idx]) if col_idx < len(row_data) else ''
                item = QTableWidgetItem(value)
                # 如果是第一列且值为34或35，设置文本颜色为红色
                if col_idx == 0 and item.text() in ['34', '35']:
                    item.setForeground(Qt.GlobalColor.red)
                self.table.setItem(row_idx + 1, col_idx, item)
        # 设置行号：第0行为空，数据区从1开始
        self.table.setVerticalHeaderItem(0, QTableWidgetItem(""))
        for row in range(1, self.table.rowCount()):
            self.table.setVerticalHeaderItem(row, QTableWidgetItem(str(row)))
        # 主动刷新所有数据行的差额、利润、总输赢列
        for row in range(1, self.table.rowCount()):
            self.refresh_diff(row)
            self.refresh_profit(row)
            self.refresh_total_win(row)

    def set_editable(self):
        for col, column_config in enumerate(self.config['columns']):
            editable = column_config.get('editable', False)
            for row in range(1, self.table.rowCount()):  # 从1开始，跳过伪表头
                # 第二列不可编辑
                if col == 1:
                    item = self.table.item(row, col)
                    if item is None:
                        item = QTableWidgetItem("")
                        self.table.setItem(row, col, item)
                    item.setFlags(Qt.ItemFlag.ItemIsSelectable | Qt.ItemFlag.ItemIsEnabled)
                    continue
                # 用户第二列（下拉框）不设置flags
                if column_config.get('type') == 'user':
                    user_indices = [i for i, c in enumerate(self.config['columns']) if c.get('type') == 'user']
                    user_index = user_indices.index(col)
                    if user_index % 3 == 1:
                        continue
                    if user_index % 3 == 2:
                        # 第三列不可编辑
                        item = self.table.item(row, col)
                        if item is None:
                            item = QTableWidgetItem("")
                            self.table.setItem(row, col, item)
                        item.setFlags(Qt.ItemFlag.ItemIsSelectable | Qt.ItemFlag.ItemIsEnabled)
                        continue
                item = self.table.item(row, col)
                if item is None:
                    item = QTableWidgetItem("")
                    self.table.setItem(row, col, item)
                if not editable:
                    item.setFlags(Qt.ItemFlag.ItemIsSelectable | Qt.ItemFlag.ItemIsEnabled)
                else:
                    item.setFlags(Qt.ItemFlag.ItemIsSelectable | Qt.ItemFlag.ItemIsEnabled | Qt.ItemFlag.ItemIsEditable)

    def closeEvent(self, event):
        # 保存数据到 config.yaml
        data = []
        for row in range(1, self.table.rowCount()):
            row_data = []
            for col in range(self.table.columnCount()):
                col_config = self.config['columns'][col]
                # 第二列下拉框，取下拉框值
                if col == 1:
                    widget = self.table.cellWidget(row, col)
                    if isinstance(widget, QComboBox):
                        row_data.append(widget.currentText())
                        continue
                # 用户第二列（下拉框），取下拉框值
                if col_config.get('type') == 'user':
                    user_indices = [i for i, c in enumerate(self.config['columns']) if c.get('type') == 'user']
                    user_index = user_indices.index(col)
                    if user_index % 3 == 1:
                        widget = self.table.cellWidget(row, col)
                        if isinstance(widget, QComboBox):
                            row_data.append(widget.currentText())
                            continue
                item = self.table.item(row, col)
                value = item.text() if item else ""
                row_data.append(value)
            # 即使该行所有单元格都为空，也保存该行数据
            data.append(row_data)
        self.config['data'] = data
        try:
            with open('config.yaml', 'w', encoding='utf-8') as file:
                yaml.dump(self.config, file, allow_unicode=True)
        except Exception as e:
            print(f"Error saving config: {e}")
        super().closeEvent(event)

    def export_to_excel(self):
        path, _ = QFileDialog.getSaveFileName(self, "导出为Excel文件", "table.xlsx", "Excel Files (*.xlsx)")
        if not path:
            return
        wb = openpyxl.Workbook()
        ws = wb.active

        # 生成导出用header
        user_subheaders = ["金额", "单双", "盈亏"]
        export_headers = []
        user_col_idx = 0
        for col in self.config['columns']:
            if col.get('type') == 'user':
                user_num = col['name']
                subheader = user_subheaders[user_col_idx % 3]
                export_headers.append(f"{user_num}-{subheader}")
                user_col_idx += 1
            elif col.get('type') != 'button':  # 不导出按钮列
                export_headers.append(col['name'])
        ws.append(export_headers)

        # 写入数据区（跳过伪表头行）
        for row in range(1, self.table.rowCount()):
            row_data = []
            for col in range(self.table.columnCount()):
                col_config = self.config['columns'][col]
                if col_config.get('type') == 'user':
                    user_indices = [i for i, c in enumerate(self.config['columns']) if c.get('type') == 'user']
                    user_index = user_indices.index(col)
                    if user_index % 3 == 1:  # 单双列
                        widget = self.table.cellWidget(row, col)
                        if isinstance(widget, QComboBox):
                            row_data.append(widget.currentText())
                        else:
                            row_data.append("")
                    else:  # 金额和盈亏列
                        item = self.table.item(row, col)
                        row_data.append(item.text() if item else "")
                elif col_config.get('type') != 'button':  # 不导出按钮列
                    item = self.table.item(row, col)
                    row_data.append(item.text() if item else "")
            ws.append(row_data)
        try:
            wb.save(path)
            QMessageBox.information(self, "导出成功", f"表格已成功导出到：{path}")
        except Exception as e:
            QMessageBox.warning(self, "导出失败", f"导出失败：{e}")

    def handle_first_col_input(self, row, col):
        # 只处理数据区的第一列
        if row == 0 or col != 0:
            return
        item = self.table.item(row, col)
        if item:
            text = item.text()
            num = re.match(r'^([1-6]{2})$', text)
            if num:
                new_text = num.group(1)
                if text != new_text:
                    self.table.blockSignals(True)
                    item.setText(new_text)
                    self.table.blockSignals(False)
            else:
                self.table.blockSignals(True)
                item.setText('')
                self.table.blockSignals(False)
        # 自动刷新第二列单双
        second_col_item = self.table.item(row, 1)
        if second_col_item is not None:
            if re.match(r'^[1-6]{2}$', item.text()):
                s = int(item.text()[0]) + int(item.text()[1])
                value = '单' if s % 2 == 1 else '双'
            else:
                value = ''
            self.table.blockSignals(True)
            second_col_item.setText(value)
            self.table.blockSignals(False)
        # 变动后刷新所有盈亏列和差额列
        self.refresh_user_profit(row)
        self.refresh_diff(row)
        self.refresh_profit(row)
        self.refresh_total_win(row)

        # 如果开奖号码是34或35，设置文本颜色为红色，否则恢复黑色
        item = self.table.item(row, col)
        if item:
            if item.text() in ['34', '35']:
                item.setForeground(Qt.GlobalColor.red)
            else:
                item.setForeground(Qt.GlobalColor.black)

    def handle_user_amount_input(self, row, col):
        # 只处理数据区
        if row == 0:
            return
        col_config = self.config['columns'][col]
        if col_config.get('type') == 'user':
            user_indices = [i for i, c in enumerate(self.config['columns']) if c.get('type') == 'user']
            user_index = user_indices.index(col)
            if user_index % 3 == 0:
                item = self.table.item(row, col)
                if item:
                    text = item.text()
                    num = re.match(r'^(\d+(?:\.\d+)?)', text)
                    if num:
                        new_text = num.group(1) + 'K'
                        if text != new_text:
                            self.table.blockSignals(True)
                            item.setText(new_text)
                            self.table.blockSignals(False)
                    else:
                        self.table.blockSignals(True)
                        item.setText('')
                        self.table.blockSignals(False)
        # 变动后刷新所有盈亏列和差额列
        self.refresh_user_profit(row)
        self.refresh_diff(row)
        self.refresh_profit(row)
        self.refresh_total_win(row)

    def handle_user_ds_changed(self, row, col):
        self.refresh_user_profit(row)
        self.refresh_diff(row)
        self.refresh_profit(row)
        self.refresh_total_win(row)

    def refresh_user_profit(self, row):
        user_indices = [i for i, c in enumerate(self.config['columns']) if c.get('type') == 'user']
        for idx, col in enumerate(user_indices):
            if idx % 3 == 2:
                # 从当前行到最后一行，依次刷新
                for r in range(row, self.table.rowCount()):
                    value = self.calculate_user_profit_accum(r, col)
                    self.table.blockSignals(True)
                    item = self.table.item(r, col)
                    if item is None:
                        item = QTableWidgetItem("")
                        self.table.setItem(r, col, item)
                    item.setText(value)
                    item.setFlags(Qt.ItemFlag.ItemIsSelectable | Qt.ItemFlag.ItemIsEnabled)
                    self.table.blockSignals(False)

    def handle_user_amount_edit_start(self, row, col):
        # 只处理数据区的用户金额列
        if row == 0:
            return
        col_config = self.config['columns'][col]
        if col_config.get('type') == 'user':
            user_indices = [i for i, c in enumerate(self.config['columns']) if c.get('type') == 'user']
            user_index = user_indices.index(col)
            if user_index % 3 == 0:
                item = self.table.item(row, col)
                if item:
                    text = item.text()
                    if text.endswith('K'):
                        self.table.blockSignals(True)
                        item.setText(text[:-1])
                        self.table.blockSignals(False)

    def refresh_diff(self, row):
        # 查找差额列索引
        diff_col = None
        for idx, col in enumerate(self.config['columns']):
            if col['name'] == '差额':
                diff_col = idx
                break
        if diff_col is None:
            return
        value = self.calculate_diff(row)
        self.table.blockSignals(True)
        item = self.table.item(row, diff_col)
        if item is None:
            item = QTableWidgetItem("")
            self.table.setItem(row, diff_col, item)
        item.setText(value)
        item.setFlags(Qt.ItemFlag.ItemIsSelectable | Qt.ItemFlag.ItemIsEnabled)
        self.table.blockSignals(False)

    def calculate_diff(self, row):
        user_indices = [i for i, c in enumerate(self.config['columns']) if c.get('type') == 'user']
        total_single = 0
        total_double = 0
        has_data = False
        for idx, col in enumerate(user_indices):
            if idx % 3 == 0:
                # 金额列
                amount_item = self.table.item(row, col)
                ds_widget = self.table.cellWidget(row, user_indices[idx + 1])
                amount = amount_item.text() if amount_item else ''
                ds = ds_widget.currentText() if ds_widget else ''
                if amount and ds:
                    has_data = True
                    try:
                        num = float(amount.rstrip('K'))
                    except Exception:
                        continue
                    if ds == '单':
                        total_single += num
                    elif ds == '双':
                        total_double += num
        if not has_data:
            return ''
        if total_single > total_double:
            diff = round(total_single - total_double, 2)
            return f'单{int(diff) if diff.is_integer() else diff}K'
        elif total_double > total_single:
            diff = round(total_double - total_single, 2)
            return f'双{int(diff) if diff.is_integer() else diff}K'
        else:
            # 当单双总值相等时，返回"单0K"
            return '单0K'

    def calculate_user_profit_accum(self, row, col):
        user_indices = [i for i, c in enumerate(self.config['columns']) if c.get('type') == 'user']
        user_index = user_indices.index(col)
        amount_col = user_indices[user_index - 2]
        ds_col = user_indices[user_index - 1]
        main_ds_col = 1

        # 本行盈亏
        amount_item = self.table.item(row, amount_col)
        ds_widget = self.table.cellWidget(row, ds_col)
        main_ds_item = self.table.item(row, main_ds_col)
        amount = amount_item.text() if amount_item else ''
        ds = ds_widget.currentText() if ds_widget else ''
        main_ds = main_ds_item.text() if main_ds_item else ''
        # 如果本行数据为空，盈亏列不显示内容
        if not (amount and ds and main_ds):
            return ''
        profit = 0
        try:
            num = float(amount.rstrip('K'))
        except Exception:
            num = 0

        # 获取开奖号码
        first_col_item = self.table.item(row, 0)
        lottery_number = first_col_item.text() if first_col_item else ''
        
        # 获取系数
        coefficient = 0.5 # 默认系数为0.5
        coefficient_col = None
        for idx, col_config in enumerate(self.config['columns']):
            if col_config['name'] == '系数':
                coefficient_col = idx
                break

        if coefficient_col is not None:
            coeff_item = self.table.item(row, coefficient_col)
            if coeff_item and coeff_item.text():
                try:
                    coeff_value = float(coeff_item.text())
                    # 系数必须大于等于0
                    if coeff_value >= 0:
                        coefficient = coeff_value
                except ValueError:
                    pass # 如果系数不是有效数字，使用默认值1

        if ds == main_ds:
            # 如果开奖号码是34或35，且用户选择与开奖结果一致，则乘以系数
            if lottery_number in ['34', '35']:
                profit = num * coefficient
            else:
                profit = num
        else:
            profit = -num

        # 加上前一行的利润值，向上查找直到找到非空且不为 '0K' 的值
        if row > 1:
            prev_profit = 0
            current_row = row - 1
            while current_row > 0:
                prev_item = self.table.item(current_row, col)  # 使用当前用户的盈亏列
                if prev_item and prev_item.text() and prev_item.text() != '0K':
                    try:
                        prev_profit = float(prev_item.text().rstrip('K'))
                        break # 找到非空且不为0K的值，停止查找
                    except Exception:
                        pass # 忽略无效值，继续向上查找
                current_row -= 1
            profit += prev_profit
            
        # 四舍五入到两位小数
        profit = round(profit, 2)
        return f'{int(profit) if profit == int(profit) else profit}K'

    def refresh_profit(self, row):
        # 查找利润列索引
        profit_col = None
        for idx, col in enumerate(self.config['columns']):
            if col['name'] == '利润':
                profit_col = idx
                break
        if profit_col is None:
            return
        value = self.calculate_profit(row)
        self.table.blockSignals(True)
        item = self.table.item(row, profit_col)
        if item is None:
            item = QTableWidgetItem("")
            self.table.setItem(row, profit_col, item)
        item.setText(value)
        item.setFlags(Qt.ItemFlag.ItemIsSelectable | Qt.ItemFlag.ItemIsEnabled)
        self.table.blockSignals(False)

    def calculate_profit(self, row):
        user_indices = [i for i, c in enumerate(self.config['columns']) if c.get('type') == 'user']
        total_single = 0  # 所有用户单的总值
        total_double = 0  # 所有用户双的总值
        has_single = False  # 是否有用户选择单
        has_double = False  # 是否有用户选择双
        has_user_data = False  # 是否有用户数据
        
        # 获取开奖号码
        first_col_item = self.table.item(row, 0)
        lottery_number = first_col_item.text() if first_col_item else ''
        
        # 计算所有用户单双的总值
        for idx, col in enumerate(user_indices):
            if idx % 3 == 0:  # 第一列（金额）
                amount_item = self.table.item(row, col)
                ds_widget = self.table.cellWidget(row, user_indices[idx + 1])
                amount = amount_item.text() if amount_item else ''
                ds = ds_widget.currentText() if ds_widget else ''
                if amount and ds:
                    has_user_data = True
                    try:
                        num = float(amount.rstrip('K'))
                        if ds == '单':
                            total_single += num
                            has_single = True
                        elif ds == '双':
                            total_double += num
                            has_double = True
                    except Exception:
                        continue
        
        # 如果没有用户数据，返回空字符串
        if not has_user_data:
            return ''
        
        # 获取系数
        coefficient = 0.5 # 默认系数为0.5
        coefficient_col = None
        for idx, col_config in enumerate(self.config['columns']):
            if col_config['name'] == '系数':
                coefficient_col = idx
                break

        if coefficient_col is not None:
            coeff_item = self.table.item(row, coefficient_col)
            if coeff_item and coeff_item.text():
                try:
                    coeff_value = float(coeff_item.text())
                    # 系数必须大于等于0
                    if coeff_value >= 0:
                        coefficient = coeff_value
                except ValueError:
                    pass # 如果系数不是有效数字，使用默认值1

        # 如果开奖号码是34或35，且所有用户中有单有双，才进行利润计算
        if lottery_number in ['34', '35'] and has_single and has_double:
            # 计算利润
            if total_single > total_double:
                profit = total_double * (1-coefficient)
            elif total_double > total_single:
                profit = total_single * (1-coefficient)
            else:
                # 如果单双总值相等，随便取一个
                profit = total_single * (1-coefficient)
        else:
            # 如果开奖号码不是34或35，或者没有单双，利润为0
            profit = 0

        # 加上前一行的利润值，向上查找直到找到非空且不为 '0K' 的值
        if row > 1:
            profit_col = None
            for idx, col in enumerate(self.config['columns']):
                if col['name'] == '利润':
                    profit_col = idx
                    break

            if profit_col is not None:
                prev_profit = 0
                current_row = row - 1
                while current_row > 0:
                    prev_item = self.table.item(current_row, profit_col)
                    if prev_item and prev_item.text() and prev_item.text() != '0K':
                        try:
                            prev_profit = float(prev_item.text().rstrip('K'))
                            break # 找到非空且不为0K的值，停止查找
                        except Exception:
                            pass # 忽略无效值，继续向上查找
                    current_row -= 1
                profit += prev_profit
            
        # 四舍五入到两位小数
        profit = round(profit, 2)
        return f'{int(profit) if profit == int(profit) else profit}K'

    def calculate_total_win(self, row):
        # 检查当前行和下面的行是否有数据
        has_data = False
        for r in range(row, self.table.rowCount()):
            first_col_item = self.table.item(r, 0)
            if first_col_item and first_col_item.text():
                has_data = True
                break
        
        if not has_data:
            return ''
        
        # 获取开奖号码和单双结果
        first_col_item = self.table.item(row, 0)
        lottery_number = first_col_item.text() if first_col_item else ''
        
        # 获取差额
        diff_col = None
        for idx, col in enumerate(self.config['columns']):
            if col['name'] == '差额':
                diff_col = idx
                break
        if diff_col is None:
            return ''
        
        diff_item = self.table.item(row, diff_col)
        diff_text = diff_item.text() if diff_item else ''
        
        # 获取系数
        coefficient = 0.5 # 默认系数为0.5
        coefficient_col = None
        for idx, col_config in enumerate(self.config['columns']):
            if col_config['name'] == '系数':
                coefficient_col = idx
                break

        if coefficient_col is not None:
            coeff_item = self.table.item(row, coefficient_col)
            if coeff_item and coeff_item.text():
                try:
                    coeff_value = float(coeff_item.text())
                    # 系数必须大于等于0
                    if coeff_value >= 0:
                        coefficient = coeff_value
                except ValueError:
                    pass # 如果系数不是有效数字，使用默认值1

        # 计算当前行的总输赢
        current_win = 0
        if lottery_number and re.match(r'^[1-6]{2}$', lottery_number):
            # 计算开奖结果的单双
            s = int(lottery_number[0]) + int(lottery_number[1])
            result_ds = '单' if s % 2 == 1 else '双'
            
            if diff_text:
                # 解析差额
                match = re.match(r'^(单|双)(\d+(?:\.\d+)?)K$', diff_text)
                if match:
                    diff_type = match.group(1)
                    diff_amount = float(match.group(2))
                    
                    if lottery_number in ['34', '35']:
                        # 如果开奖号码是34或35，且差额单双和开奖单双一样，总输赢 = 差额 × 系数
                        if result_ds == diff_type:
                            current_win = diff_amount * coefficient
                        else:
                            current_win = -diff_amount
                    else:
                        # 其他开奖号码，按原来的逻辑计算
                        if result_ds == diff_type:
                            current_win = diff_amount
                        else:
                            current_win = -diff_amount
            
        # 加上前一行的总输赢
        if row > 1:
            total_win_col = None
            for idx, col in enumerate(self.config['columns']):
                if col['name'] == '总输赢':
                    total_win_col = idx
                    break
            if total_win_col is not None:
                prev_item = self.table.item(row - 1, total_win_col)
                if prev_item:
                    prev_val = prev_item.text()
                    try:
                        prev_win = float(prev_val.rstrip('K')) if prev_val else 0
                        current_win += prev_win
                    except Exception:
                        pass
        
        # 四舍五入到两位小数
        current_win = round(current_win, 2)
        return f'{int(current_win) if current_win == int(current_win) else current_win}K'

    def refresh_total_win(self, row):
        # 查找总输赢列索引
        total_win_col = None
        for idx, col in enumerate(self.config['columns']):
            if col['name'] == '总输赢':
                total_win_col = idx
                break
        if total_win_col is None:
            return
        value = self.calculate_total_win(row)
        self.table.blockSignals(True)
        item = self.table.item(row, total_win_col)
        if item is None:
            item = QTableWidgetItem("")
            self.table.setItem(row, total_win_col, item)
        item.setText(value)
        item.setFlags(Qt.ItemFlag.ItemIsSelectable | Qt.ItemFlag.ItemIsEnabled)
        self.table.blockSignals(False)

    def handle_half_amount(self, row, ds_type):
        user_indices = [i for i, c in enumerate(self.config['columns']) if c.get('type') == 'user']
        for idx, col in enumerate(user_indices):
            if idx % 3 == 1:  # 用户单双列
                ds_widget = self.table.cellWidget(row, col)
                if ds_widget and ds_widget.currentText() == ds_type:
                    # 找到对应的金额列
                    amount_col = user_indices[idx - 1]
                    amount_item = self.table.item(row, amount_col)
                    if amount_item and amount_item.text():
                        try:
                            # 获取当前金额并减半
                            current_amount = float(amount_item.text().rstrip('K'))
                            new_amount = round(current_amount / 2, 2)
                            # 更新金额
                            self.table.blockSignals(True)
                            amount_item.setText(f'{int(new_amount) if new_amount.is_integer() else new_amount}K')
                            self.table.blockSignals(False)
                            # 刷新相关计算
                            self.refresh_user_profit(row)
                            self.refresh_diff(row)
                            self.refresh_profit(row)
                            self.refresh_total_win(row)
                        except Exception:
                            pass

    def import_from_excel(self):
        path, _ = QFileDialog.getOpenFileName(self, "选择Excel文件", "", "Excel Files (*.xlsx)")
        if not path:
            return
            
        try:
            wb = openpyxl.load_workbook(path)
            ws = wb.active
            
            # 读取表头
            headers = [cell.value for cell in ws[1]]
            
            # 验证表头格式
            user_headers = []
            normal_headers = []
            for header in headers:
                if '-' in str(header):  # 用户列
                    user_headers.append(header)
                else:  # 普通列
                    normal_headers.append(header)
            
            # 计算用户数量
            user_count = len(user_headers) // 3
            if user_count == 0:
                QMessageBox.warning(self, "导入失败", "Excel文件中没有找到用户数据")
                return
                
            # 清空当前表格
            self.table.clear()
            self.table.setRowCount(0)
            self.table.setColumnCount(0)
            
            # 重新配置用户数量
            self.generate_user_columns(user_count)
            self.config['data'] = []
            
            # 设置表格大小
            self.user_col_indices = [idx for idx, col in enumerate(self.config['columns']) if col.get('type') == USER_TYPE]
            self.normal_col_indices = [idx for idx, col in enumerate(self.config['columns']) if col.get('type') != USER_TYPE]
            self.user_count = len(self.user_col_indices) // 3
            self.total_columns = len(self.config['columns'])
            self.data_rows = max(ws.max_row - 1, 100)  # 减去表头行
            self.table.setColumnCount(self.total_columns)
            self.table.setRowCount(self.data_rows + 1)
            
            # 初始化表头
            self.init_multilevel_header()
            
            # 导入数据
            for row_idx, row in enumerate(ws.iter_rows(min_row=2), 1):  # 从第二行开始（跳过表头）
                for col_idx, cell in enumerate(row):
                    if col_idx >= len(headers):
                        continue
                        
                    header = headers[col_idx]
                    if '-' in str(header):  # 用户列
                        # 解析用户列信息
                        user_num, subheader = header.split('-')
                        user_idx = int(user_num.replace('用户', '')) - 1
                        if subheader == '金额':
                            col = self.user_col_indices[user_idx * 3]
                            item = QTableWidgetItem(str(cell.value) if cell.value else "")
                            self.table.setItem(row_idx, col, item)
                        elif subheader == '单双':
                            col = self.user_col_indices[user_idx * 3 + 1]
                            combo = QComboBox()
                            combo.addItems(['', '单', '双'])
                            combo.setCurrentText(str(cell.value) if cell.value in ['单', '双'] else '')
                            combo.currentTextChanged.connect(lambda _, r=row_idx, c=col: self.handle_user_ds_changed(r, c))
                            self.table.setCellWidget(row_idx, col, combo)
                        elif subheader == '盈亏':
                            col = self.user_col_indices[user_idx * 3 + 2]
                            item = QTableWidgetItem(str(cell.value) if cell.value else "")
                            self.table.setItem(row_idx, col, item)
                    else:  # 普通列
                        # 找到对应的列索引
                        for idx, col in enumerate(self.config['columns']):
                            if col['name'] == header:
                                # 导入时，如果header是'系数'且cell.value为空，则保持为空
                                value = str(cell.value) if cell.value is not None else ''
                                item = QTableWidgetItem(value)
                                self.table.setItem(row_idx, idx, item)
                                break
            
            # 创建减半操作按钮
            for row_idx in range(1, self.table.rowCount()):
                for col_idx, col_config in enumerate(self.config['columns']):
                    if col_config.get('type') == 'button':
                        # 创建按钮容器
                        button_widget = QWidget()
                        button_layout = QHBoxLayout(button_widget)
                        button_layout.setContentsMargins(2, 2, 2, 2)
                        button_layout.setSpacing(2)
                        
                        # 创建单减半按钮
                        single_btn = QPushButton("单减半")
                        single_btn.setFixedHeight(25)
                        single_btn.clicked.connect(lambda checked, r=row_idx: self.handle_half_amount(r, '单'))
                        button_layout.addWidget(single_btn)
                        
                        # 创建双减半按钮
                        double_btn = QPushButton("双减半")
                        double_btn.setFixedHeight(25)
                        double_btn.clicked.connect(lambda checked, r=row_idx: self.handle_half_amount(r, '双'))
                        button_layout.addWidget(double_btn)
                        
                        self.table.setCellWidget(row_idx, col_idx, button_widget)
            
            # 刷新所有计算
            for row in range(1, self.table.rowCount()):
                self.refresh_user_profit(row)
                self.refresh_diff(row)
                self.refresh_profit(row)
                self.refresh_total_win(row)
            
            QMessageBox.information(self, "导入成功", "数据已成功导入")
            
        except Exception as e:
            QMessageBox.warning(self, "导入失败", f"导入失败：{str(e)}")

    def add_user(self):
        # 添加新用户
        self.user_count += 1
        
        # 找到利润列的索引
        profit_col_index = None
        for idx, col in enumerate(self.config['columns']):
            if col['name'] == '利润':
                profit_col_index = idx
                break
        
        if profit_col_index is None:
            # 如果找不到利润列，就添加到末尾
            for i in range(3):
                self.config['columns'].append({
                    'name': f'用户{self.user_count}',
                    'type': USER_TYPE,
                    'width': 60,
                    'editable': True
                })
        else:
            # 在利润列之前插入新用户列
            new_columns = []
            for i in range(3):
                new_columns.append({
                    'name': f'用户{self.user_count}',
                    'type': USER_TYPE,
                    'width': 60,
                    'editable': True
                })
            
            # 重新组织列
            self.config['columns'] = (
                self.config['columns'][:profit_col_index] + 
                new_columns + 
                self.config['columns'][profit_col_index:]
            )
        
        # 更新配置
        self.total_columns = len(self.config['columns'])
        self.user_col_indices = [idx for idx, col in enumerate(self.config['columns']) if col.get('type') == USER_TYPE]
        
        # 保存当前数据
        data = []
        for row in range(1, self.table.rowCount()):
            row_data = []
            for col in range(min(self.table.columnCount(), len(self.config['columns']))):
                if col >= len(self.config['columns']):
                    continue
                    
                col_config = self.config['columns'][col]
                if col_config.get('type') == 'user':
                    user_indices = [i for i, c in enumerate(self.config['columns']) if c.get('type') == 'user']
                    user_index = user_indices.index(col)
                    if user_index % 3 == 1:
                        widget = self.table.cellWidget(row, col)
                        if isinstance(widget, QComboBox):
                            row_data.append(widget.currentText())
                            continue
                item = self.table.item(row, col)
                value = item.text() if item else ""
                row_data.append(value)
            if any(str(cell).strip() for cell in row_data):
                data.append(row_data)
        
        # 更新配置中的数据
        self.config['data'] = data
        
        # 保存配置
        with open('config.yaml', 'w', encoding='utf-8') as file:
            yaml.dump(self.config, file, allow_unicode=True)
        
        # 刷新表格
        self.refresh_table()
        
        # 启用删除用户操作
        for action in self.menuBar().actions():
            if action.text() == "设置":
                for sub_action in action.menu().actions():
                    if sub_action.text() == "用户管理":
                        for user_action in sub_action.menu().actions():
                            if user_action.text() == "删除用户":
                                user_action.setEnabled(True)
                                break
                        break
                break
        
        # 更新表头widget
        self.update_header_widget()

    def remove_user(self):
        # 如果只有一个用户，不允许删除
        if self.user_count <= 1:
            QMessageBox.warning(self, "无法删除", "至少需要保留一个用户")
            return
            
        # 创建用户选择对话框
        dialog = QDialog(self)
        dialog.setWindowTitle("选择要删除的用户")
        layout = QVBoxLayout(dialog)
        
        # 创建下拉框
        combo = QComboBox()
        # 获取所有用户名称
        user_names = []
        for i in range(self.user_count):
            user_col = self.user_col_indices[i * 3]
            user_name = self.config['columns'][user_col]['name']
            user_names.append(user_name)
        combo.addItems(user_names)
        layout.addWidget(combo)
        
        # 添加按钮
        button_layout = QHBoxLayout()
        ok_button = QPushButton("确定")
        cancel_button = QPushButton("取消")
        button_layout.addWidget(ok_button)
        button_layout.addWidget(cancel_button)
        layout.addLayout(button_layout)
        
        # 连接按钮信号
        ok_button.clicked.connect(dialog.accept)
        cancel_button.clicked.connect(dialog.reject)
        
        # 显示对话框
        if dialog.exec() == QDialog.DialogCode.Accepted:
            selected_index = combo.currentIndex()
            
            # 确认对话框
            reply = QMessageBox.question(self, '确认删除', 
                                       f'确定要删除用户"{user_names[selected_index]}"吗？此操作不可恢复。',
                                       QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
                                       QMessageBox.StandardButton.No)
            
            if reply == QMessageBox.StandardButton.Yes:
                # 计算要删除的列的起始索引
                start_idx = self.user_col_indices[selected_index * 3]
                
                # 删除该用户的三列
                del self.config['columns'][start_idx:start_idx + 3]
                
                self.user_count -= 1
                self.total_columns = len(self.config['columns'])
                self.user_col_indices = [idx for idx, col in enumerate(self.config['columns']) if col.get('type') == USER_TYPE]
                
                # 保存配置
                with open('config.yaml', 'w', encoding='utf-8') as file:
                    yaml.dump(self.config, file, allow_unicode=True)
                
                # 刷新表格
                self.refresh_table()
                
                # 如果删除后只剩一个用户，禁用删除操作
                if self.user_count <= 1:
                    for action in self.menuBar().actions():
                        if action.text() == "设置":
                            for sub_action in action.menu().actions():
                                if sub_action.text() == "用户管理":
                                    for user_action in sub_action.menu().actions():
                                        if user_action.text() == "删除用户":
                                            user_action.setEnabled(False)
                                            break
                                    break
                            break
                
                # 更新表头widget
                self.update_header_widget()

    def refresh_table(self):
        self.table.blockSignals(True)
        # 保存当前数据
        data = []
        for row in range(1, self.table.rowCount()):
            row_data = []
            for col in range(min(self.table.columnCount(), len(self.config['columns']))):
                if col >= len(self.config['columns']):
                    continue
                col_config = self.config['columns'][col]
                if col_config.get('type') == 'user':
                    try:
                        user_indices = [i for i, c in enumerate(self.config['columns']) if c.get('type') == 'user']
                        if col in user_indices:
                            user_index = user_indices.index(col)
                            if user_index % 3 == 1:
                                widget = self.table.cellWidget(row, col)
                                if isinstance(widget, QComboBox):
                                    row_data.append(widget.currentText())
                                    continue
                    except ValueError:
                        pass
                item = self.table.item(row, col)
                value = item.text() if item else ""
                row_data.append(value)
            if any(str(cell).strip() for cell in row_data):
                data.append(row_data)
        # 清空表格
        self.table.clear()
        self.table.setRowCount(0)
        self.table.setColumnCount(0)
        # 重新设置表格大小
        self.table.setColumnCount(self.total_columns)
        self.table.setRowCount(self.data_rows + 1)
        # 保存数据到配置
        self.config['data'] = data
        # 重新初始化表头和数据
        self.init_multilevel_header()  # 这里会重新计算并设置窗口宽度
        self.fill_table_data()
        self.set_editable()
        # 恢复数据
        for row_idx, row_data in enumerate(data):
            for col_idx, value in enumerate(row_data):
                if col_idx >= len(self.config['columns']):
                    continue
                col_config = self.config['columns'][col_idx]
                if col_config.get('type') == 'user':
                    try:
                        user_indices = [i for i, c in enumerate(self.config['columns']) if c.get('type') == 'user']
                        if col_idx in user_indices:
                            user_index = user_indices.index(col_idx)
                            if user_index % 3 == 1:
                                widget = self.table.cellWidget(row_idx + 1, col_idx)
                                if isinstance(widget, QComboBox):
                                    widget.setCurrentText(value)
                                    continue
                    except ValueError:
                        pass
                item = self.table.item(row_idx + 1, col_idx)
                if item:
                    # 恢复数据时，如果是系数列且值为空，则保持为空
                    item.setText(value)
        # 清空新增用户的列
        user_indices = [i for i, c in enumerate(self.config['columns']) if c.get('type') == 'user']
        new_user_start = (self.user_count - 1) * 3  # 新增用户的起始索引
        for row in range(1, self.table.rowCount()):
            for i in range(3):  # 每个用户有3列
                col_idx = user_indices[new_user_start + i]
                if i == 1:  # 单双列
                    widget = self.table.cellWidget(row, col_idx)
                    if isinstance(widget, QComboBox):
                        widget.setCurrentText('')
                else:  # 金额和盈亏列
                    item = self.table.item(row, col_idx)
                    if item:
                        item.setText('')
        # 更新表头widget
        self.update_header_widget()
        # 更新行号widget
        self.update_row_header_widget()
        self.table.blockSignals(False)
        # 防止刷新后窗口黑屏
        self.show()

def main():
    app = QApplication(sys.argv)
    window = ConfigurableTable()
    window.show()
    sys.exit(app.exec())

if __name__ == '__main__':
    main()